#ifndef __FLASH_DRIVER_H
#define __FLASH_DRIVER_H

#ifdef __cplusplus
extern "C" {
#endif
#include "main.h"
#include "stm32g0xx_hal.h"
#include "flash.h"
#include "string.h"

#define STM32_FLASH_SIZE 	32 	 	//??STM32?FLASH????(???K)
#define STM_SECTOR_SIZE	    2048    //2K??
 
#define STM32_FLASH_BASE    0x08000000 		//STM32 FLASH?????
 
//??28672 = 7000,??77FF
//#define FLASH_USER_START_ADDR 0x08007000           /* ?13? Start @ of user Flash area */
#define FLASH_USER_END_ADDR   0x0800FFFF         /* ?13? End @ of user Flash area */

#define FLASH_PAGE_BYTES 2048

#define FLASH_USER_PAGE_ADDR  0x0800F800
#define FLASH_PAGE_FLAG_ADDR FLASH_USER_PAGE_ADDR

#define FLASH_SERVICE_ID_ADDR (FLASH_PAGE_FLAG_ADDR+FLASH_PAGE_FLAG_LEN)
#define FLASH_SERVICE_ID_LEN  (4*sizeof(uint64_t))

//#define FLASH_TIMER_ADDR (FLASH_USER_PAGE_ADDR+FLASH_SERVICE_ID_LEN)
//#define FLASH_TIMER_LEN  (sizeof(uint64_t))

// Flash????
typedef enum {
    FLASH_OK = 0,
    FLASH_ERROR,
    FLASH_INVALID_ADDRESS,
    FLASH_NOT_ERASED,
    FLASH_WRITE_FAILED,
    FLASH_ERASE_FAILED,
    FLASH_SIZE_ERROR
} FlashStatus;

// Flash?????
typedef struct {
    uint32_t start_address;   // Flash????
    uint32_t end_address;     // Flash????
    uint32_t sector_size;     // ????
    uint32_t page_size;       // ???(??????????)
} FlashConfig;

struct FlashData {
	char srvName[32];
	char self[17];
	uint8_t secret[17];
	uint32_t uid;
	uint8_t net;
	uint8_t freq;
	uint8_t baud;
	uint8_t power;
	uint8_t th;
	uint8_t sf;
	uint8_t cr;
	uint32_t empty;
};

#define SERVER_LEN 32
#define SECRET_LEN 16
// ?????
FlashStatus Flash_Init(const FlashConfig *config);

// ????
FlashStatus Flash_EraseSector(uint32_t sector_index);
FlashStatus Flash_EraseRange(uint32_t start_addr, uint32_t length);

// ???
FlashStatus Flash_VerifyBuffer(uint32_t address, const uint8_t *data, uint32_t length);

// ????
uint32_t Flash_GetSectorIndex(uint32_t address);
uint32_t Flash_GetSectorStartAddress(uint32_t sector_index);
uint8_t Flash_IsErased(uint32_t address, uint32_t length);

extern struct FlashData * GET_FLASH_DATA(void);
extern HAL_StatusTypeDef FlashErase(uint32_t addr);
//extern HAL_StatusTypeDef FlashSetLoraConf(uint8_t,uint8_t,uint8_t,uint8_t);
extern HAL_StatusTypeDef FlashSetLoraConf(char *server, uint8_t freq, uint8_t net, uint8_t baud, uint8_t power, uint8_t secret[], uint8_t sf, uint8_t cr);
extern void GetUID(char output[17]);
extern HAL_StatusTypeDef FlashSetTHConf(uint8_t status);
#ifdef __cplusplus
}
#endif

#endif /* __FLASH_DRIVER_H */
